/**
 */
package fUML.Semantics.Classes.Kernel;

import fUML.Syntax.Classes.Kernel.StructuralFeature;

import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EObject;

/**
 * <!-- begin-user-doc -->
 * A representation of the model object '<em><b>Feature Value</b></em>'.
 * <!-- end-user-doc -->
 *
 * <!-- begin-model-doc -->
 * A feature value gives the value(s) that a single structural feature has in a
 *                 specific structured value.
 * <!-- end-model-doc -->
 *
 * <p>
 * The following features are supported:
 * <ul>
 *   <li>{@link fUML.Semantics.Classes.Kernel.FeatureValue#getFeature <em>Feature</em>}</li>
 *   <li>{@link fUML.Semantics.Classes.Kernel.FeatureValue#getValues <em>Values</em>}</li>
 *   <li>{@link fUML.Semantics.Classes.Kernel.FeatureValue#getPosition <em>Position</em>}</li>
 * </ul>
 * </p>
 *
 * @see fUML.Semantics.Classes.Kernel.KernelPackage#getFeatureValue()
 * @model
 * @generated
 */
public interface FeatureValue extends EObject {
	/**
	 * Returns the value of the '<em><b>Feature</b></em>' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The structural feature being given value(s).
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Feature</em>' reference.
	 * @see #setFeature(StructuralFeature)
	 * @see fUML.Semantics.Classes.Kernel.KernelPackage#getFeatureValue_Feature()
	 * @model required="true" ordered="false"
	 * @generated
	 */
	StructuralFeature getFeature();

	/**
	 * Sets the value of the '{@link fUML.Semantics.Classes.Kernel.FeatureValue#getFeature <em>Feature</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Feature</em>' reference.
	 * @see #getFeature()
	 * @generated
	 */
	void setFeature(StructuralFeature value);

	/**
	 * Returns the value of the '<em><b>Values</b></em>' containment reference list.
	 * The list contents are of type {@link fUML.Semantics.Classes.Kernel.Value}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The values of for the feature. Zero or more values are possible, as
	 *                   constrained by the multiplicity of the feature.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Values</em>' containment reference list.
	 * @see fUML.Semantics.Classes.Kernel.KernelPackage#getFeatureValue_Values()
	 * @model containment="true"
	 * @generated
	 */
	EList<Value> getValues();

	/**
	 * Returns the value of the '<em><b>Position</b></em>' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The position of this feature value in a set of ordered values for a feature of
	 *                   an association.
	 *  [This is only relevant if the feature value is for a link
	 *                   and the feature is ordered.]
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Position</em>' attribute.
	 * @see #setPosition(int)
	 * @see fUML.Semantics.Classes.Kernel.KernelPackage#getFeatureValue_Position()
	 * @model ordered="false"
	 * @generated
	 */
	int getPosition();

	/**
	 * Sets the value of the '{@link fUML.Semantics.Classes.Kernel.FeatureValue#getPosition <em>Position</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Position</em>' attribute.
	 * @see #getPosition()
	 * @generated
	 */
	void setPosition(int value);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Determine if this feature value has an equal set of values as another
	 *                   feature value.
	 *  // If the feature is ordered, then the values also have to
	 *                   be in the same order.
	 *  
	 *  boolean equal = true;
	 *  
	 *                   if (this.values.size() != other.values.size()) {
	 *  equal = false;
	 *                   
	 *  } else {
	 *  
	 *  // Debug.println("[hasEqualValues] feature =
	 *                   " + this.feature.name + ", " + this.values.size() + " value(s).");
	 *                   
	 *  if (this.feature.multiplicityElement.isOrdered) {
	 *  int i =
	 *                   1;
	 *  while (equal & i <= this.values.size()) {
	 *                   equal = this.values.getValue(i-1).equals(other.values.getValue(i-1));
	 *  i =
	 *                   i + 1;
	 *  }
	 *  
	 *  } else {
	 *  // Note: otherFeatureValues
	 *                   is used here solely as a holder for a copy of the list of other values,
	 *                   // since the Java to UML mapping conventions do not allow "remove" on a local list
	 *                   variable.
	 *  FeatureValue otherFeatureValues = new FeatureValue();
	 *                   ValueList values = other.values;
	 *  for (int i=0; i < values.size();
	 *                   i++) {
	 *  Value value = values.getValue(i);
	 *                   otherFeatureValues.values.addValue(value);
	 *  }
	 *  
	 *  int i =
	 *                   1;
	 *  while (equal & i <= this.values.size()) {
	 *  //
	 *                   Debug.println("[hasEqualValues] This value [" + (i-1) + "] = " +
	 *                   this.values.getValue(i-1));
	 *  
	 *  boolean matched = false;
	 *                   int j = 1;
	 *  while (!matched & j <=
	 *                   otherFeatureValues.values.size()) {
	 *  if
	 *                   (this.values.getValue(i-1).equals(otherFeatureValues.values.getValue(j-1)))
	 *                   {
	 *  // Debug.println("[hasEqualValues] Other value [" + (j-1) + "] = " +
	 *                   otherFeatureValues.values.getValue(j-1));
	 *  matched = true;
	 *                   otherFeatureValues.values.remove(j-1);
	 *  }
	 *  j = j + 1;
	 *                   }
	 *  
	 *  equal = matched;
	 *  i = i + 1;
	 *  }
	 *                   }
	 *  }
	 *  
	 *  return equal;
	 *  
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false" otherRequired="true" otherOrdered="false"
	 * @generated
	 */
	boolean hasEqualValues(FeatureValue other);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Create a copy of this feature value.
	 *  
	 *  FeatureValue
	 *                   newValue = new FeatureValue();
	 *  
	 *  newValue.feature =
	 *                   this.feature;
	 *  newValue.position = this.position;
	 *  
	 *                   ValueList values = this.values;
	 *  for (int i = 0; i < values.size();
	 *                   i ++) {
	 *  Value value = values.getValue(i);
	 *                   newValue.values.addValue(value.copy());
	 *  }
	 *  
	 *  return
	 *                   newValue;
	 *  
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false"
	 * @generated
	 */
	FeatureValue copy();

} // FeatureValue
